package com.yjc.drygoods.ware.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yjc.common.constant.InventoryAlertsProcessStatusEnum;
import com.yjc.common.constant.PurchaseDetailStatusEnum;
import com.yjc.common.utils.R;
import com.yjc.drygoods.ware.dao.PurchaseDetailDao;
import com.yjc.drygoods.ware.entity.InventoryAlertsEntity;
import com.yjc.drygoods.ware.entity.PurchaseDetailEntity;
import com.yjc.drygoods.ware.entity.WareInfoEntity;
import com.yjc.drygoods.ware.entity.WareSpuEntity;
import com.yjc.drygoods.ware.exception.NotClearStockException;
import com.yjc.drygoods.ware.exception.PurchaseNumException;
import com.yjc.drygoods.ware.feign.ProductFeignService;
import com.yjc.drygoods.ware.feign.SearchFeignService;
import com.yjc.drygoods.ware.service.InventoryAlertsService;
import com.yjc.drygoods.ware.service.PurchaseDetailService;
import com.yjc.drygoods.ware.service.WareInfoService;
import com.yjc.drygoods.ware.service.WareSpuService;
import com.yjc.drygoods.ware.to.SpuInfoTo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yjc.common.utils.PageUtils;
import com.yjc.common.utils.Query;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Slf4j
@Service("purchaseDetailService")
public class PurchaseDetailServiceImpl extends ServiceImpl<PurchaseDetailDao, PurchaseDetailEntity> implements PurchaseDetailService {

    @Autowired
    WareSpuService wareSpuService;

    @Autowired
    InventoryAlertsService inventoryAlertsService;

    @Autowired
    ProductFeignService productFeignService;

    @Autowired
    WareInfoService wareInfoService;

    @Autowired
    SearchFeignService searchFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseDetailEntity> queryWrapper = new QueryWrapper<>();
        /**
         * status: 0,//状态
         *    wareId: 1,//仓库id
         */
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and(i -> i.eq("purchase_id", key).or().or().like("spu_name", key));
        }
        String status = (String) params.get("status");
        if (!StringUtils.isEmpty(status)) {
            queryWrapper.eq("status", status);
        }
        String wareId = (String) params.get("wareId");
        if (!StringUtils.isEmpty(wareId)) {
            queryWrapper.eq("ware_id", wareId);
        }
        IPage<PurchaseDetailEntity> page = this.page(
                new Query<PurchaseDetailEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public List<PurchaseDetailEntity> listDetailByPurchaseId(Long id) {
        return this.baseMapper.selectList(new QueryWrapper<PurchaseDetailEntity>().eq("purchase_id", id));
    }

    @Override
    public void savePurchaseDetail(PurchaseDetailEntity purchaseDetail) {
        if (purchaseDetail.getSpuNum() == null) {
            //当采购数量为空时，分析es中的上一年(或者上两年)的当前月份的平均每批进货数，得到需要采购的数量
            R r = searchFeignService.searchPurchaseSpuNum(purchaseDetail.getSpuId());
            if (r.getCode() == 0 && !r.get("data").equals("Infinity")) {
                Double data = (Double) r.get("data");
                log.info("data:{}", data);
                purchaseDetail.setSpuNum(data);
            }
        }
        if (purchaseDetail.getSpuNum() != null && (purchaseDetail.getSpuNum() > 300 || purchaseDetail.getSpuNum() < 0)) {
            throw new PurchaseNumException("采购数量：" + purchaseDetail.getSpuNum());
        }
        //1.根据商品id，去`wms_ware_spu`表查询该商品库存是否已清空。没有则不能新增采购需求
        Boolean singleSpuWare = wareSpuService.getSingleSpuWare(purchaseDetail.getSpuId());
        //2.查询同一spuId的采购需求，除了采购完成和采购失败外，如果已存在一个，不允许有另外一个采购需求
        int count = this.count(new QueryWrapper<PurchaseDetailEntity>()
                .eq("spu_id", purchaseDetail.getSpuId())
                .and(i -> i.ne("status", 3).ne("status", 4)));
        //2.设置该采购需求的存放仓库名称
        WareInfoEntity wareInfo = wareInfoService.getById(purchaseDetail.getWareId());
        purchaseDetail.setWareName(wareInfo.getName());
        //该商品无库存时可添加采购需求
        if (!singleSpuWare) {
            if (count < 1) {
                Long spuId = purchaseDetail.getSpuId();
                log.info("spuId:{}", spuId);
                R r = productFeignService.spuInfo(spuId);
                if (r.getCode() != 0) {
                    throw new RuntimeException("干货远程服务调用异常");
                }
                SpuInfoTo spuInfo = r.getData("spuInfo", new TypeReference<SpuInfoTo>() {
                });
                purchaseDetail.setSpuName(spuInfo.getSpuName());
                this.save(purchaseDetail);
            }
        } else {
            throw new NotClearStockException("请清空该商品库存！");
        }
    }

    @Transactional
    @Override
    public void addPurchaseItem(InventoryAlertsEntity inventoryAlertsEntity) {
        PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
        //分析es中的上一年(或者上两年)的当前季节的平均每批进货数，得到需要采购的数量
        R rSearch = searchFeignService.searchPurchaseSpuNum(inventoryAlertsEntity.getSpuId());
        if (rSearch.getCode() == 0 && !rSearch.get("data").equals("Infinity")) {
            Double data = (Double) rSearch.get("data");
            log.info("data:{}", data);
            purchaseDetailEntity.setSpuNum(data);
        }
        if (inventoryAlertsEntity.getSpuNum() != null && (inventoryAlertsEntity.getSpuNum() > 300 || inventoryAlertsEntity.getSpuNum() < 0)) {
            throw new PurchaseNumException();
        }
        purchaseDetailEntity.setUpdateTime(new Date());
        purchaseDetailEntity.setStatus(0);
        purchaseDetailEntity.setSpuId(inventoryAlertsEntity.getSpuId());
        //从库存预警加入的采购需求，统一放入1号仓库
        purchaseDetailEntity.setWareId(1L);
        WareInfoEntity wareInfoEntity = wareInfoService.getById(1L);
        purchaseDetailEntity.setWareName(wareInfoEntity.getName());
        //1.根据商品id，去`wms_ware_spu`表查询该商品库存是否已清空。没有则不能新增采购需求
        Boolean singleSpuWare = wareSpuService.getSingleSpuWare(purchaseDetailEntity.getSpuId());
        int count = this.count(new QueryWrapper<PurchaseDetailEntity>()
                .eq("spu_id", inventoryAlertsEntity.getSpuId())
                .and(i -> i.ne("status", 3).ne("status", 4)));
        //该商品无库存时才可添加采购需求
        Double spuStock = wareSpuService.getSingleSpuWareStock(inventoryAlertsEntity.getSpuId());
        if (!singleSpuWare) {
            //是否已存在该干货的采购需求(新建、已分配、正在采购)，已存在则不再添加
            if (count < 1) {
                Long spuId = purchaseDetailEntity.getSpuId();
                R r = productFeignService.spuInfo(spuId);
                if (r.getCode() != 0) {
                    throw new RuntimeException("干货远程服务调用异常");
                }
                SpuInfoTo spuInfo = r.getData("spuInfo", new TypeReference<SpuInfoTo>() {
                });
                purchaseDetailEntity.setSpuName(spuInfo.getSpuName());
                this.save(purchaseDetailEntity);
            }
            //修改该商品的库存预警为已处理
            inventoryAlertsEntity.setProcessStatus(InventoryAlertsProcessStatusEnum.PROCESSED.getCode());
            inventoryAlertsEntity.setProcessTime(new Date());
            inventoryAlertsEntity.setSpuNum(spuStock);
            inventoryAlertsService.updateById(inventoryAlertsEntity);
        } else {
            //修改该商品的库存预警为库存未清空
            inventoryAlertsEntity.setProcessStatus(InventoryAlertsProcessStatusEnum.INVENTORY_IS_NOT_EMPTY.getCode());
            inventoryAlertsEntity.setProcessTime(new Date());
            inventoryAlertsEntity.setSpuNum(spuStock);
            inventoryAlertsService.updateById(inventoryAlertsEntity);
            throw new NotClearStockException("请清空该商品库存！");
        }

    }

    /**
     * 定时任务：每年扫描采购详情，将去年的所有的采购成功的采购需求加入es中
     */
    @XxlJob(value = "addPurchaseDetailToEs")
    public void addPurchaseDetailToEs() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.add(Calendar.YEAR, -1);
        Date oldYear = calendar.getTime();
        calendar.add(Calendar.YEAR, +1);
        Date nowYear = calendar.getTime();
        log.info("oldYear:{},nowYear:{}", oldYear, nowYear);
        List<PurchaseDetailEntity> purchaseDetails = this.list(new QueryWrapper<PurchaseDetailEntity>()
                .between("update_time", oldYear, nowYear).eq("status", PurchaseDetailStatusEnum.FINISHED.getCode()));
//        purchaseDetails.forEach(System.out::println);
        R r = searchFeignService.saveOldYearPurchaseDetail(purchaseDetails);
        log.info("干货采购需求录入结果：{}", r.get("data"));

    }

}